#include "gameboardorganizer.h"
#include "gametable.h"
#include "ghostboarditems.h"
#include "tileboarditems.h"
#include <QPainter>
#include "player.h"
#include "infoboard.h"
#include "playeritems.h"
#include "gameanimation.h"
#include "windowskin.h"

GameBoardOrganizer::GameBoardOrganizer(GameTable *t)
    : QGraphicsObject(t), _table(t), _board(0)
{
}

GameBoardOrganizer::GameBoardOrganizer(GameTable *t, GameBoardOrganizer *b)
    : QGraphicsObject(b), _table(t), _board(b)
{
}

QRectF GameBoardOrganizer::boundingRect() const{
    //organizer normally does nothing. can override to give a diffent bound.
    return QRectF();
}

void GameBoardOrganizer::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
    //similar with boundingRect
}

//**********************************CENTER TABLE********************************//

/*

  GHOST BOARD CLASS


  */

GhostBoard::GhostBoard(GameTable *t, GameBoardOrganizer *b, GSColor color)
    :GameBoardOrganizer(t, b),_c(color), _p(0)
{
    bottom = new GhostBoardBottom(this);
    phead = new PlayerHeadArea(this);
    phead->moveBy(GhostSlot::WIDTH*3/2+GhostSlot::HEIGHT/2-10,
                  0);

    int slotWidth = GhostSlot::WIDTH;
    for(int i = 0; i<3; i++){
        GhostSlot* singleSlot = new GhostSlot(this);
        singleSlot->moveBy(-3/2*slotWidth+i*slotWidth, 0);
        singleSlot->createAnim();
        slot << singleSlot;
        connect(singleSlot, SIGNAL(clicked(GhostSlot*)), this, SIGNAL(clicked(GhostSlot*)));
    }

    top = new GhostBoardTop(this);
    _seal_skill_counter = 0;
}

QPixmap GhostBoard::getPlayerPixmap(){
    QPixmap p;
    switch(_c){
    case YELLOW:
        p = QPixmap(":/playerHead/images/y_taoist.png");
        break;
    case RED:
        p = QPixmap(":/playerHead/images/r_taoist.png");
        break;
    case GREEN:
        p = QPixmap(":/playerHead/images/g_taoist.png");
        break;
    case BLUE:
        p = QPixmap(":/playerHead/images/b_taoist.png");
        break;
    default:
        break;
    }
    return p;
}

QColor GhostBoard::getColor(){
    QColor value;
    switch(_c){
    case YELLOW:
        value = QColor(235, 211, 78, 255);
        break;
    case RED:
        value = QColor(208, 54, 54, 255);
        break;
    case GREEN:
        value = QColor(110, 216, 92, 255);
        break;
    case BLUE:
        value = QColor(78, 130, 235, 255);
        break;
    default:
        break;
    }
    return value;
}

GSColor GhostBoard::getGSColor(){
    return _c;
}

void GhostBoard::setId(int id){
    _id = id;
    phead->createHeadForBoard(_c, id);
    bottom->createBoardBottom(_c);
}

void GhostBoard::setPlayer(Player *p){
    _p = p;
    _p->setPlayerHead(getPlayerPixmap());
}

Player* GhostBoard::getPlayer(){
    return _p;
}


int GhostBoard::getBoardIndex(){
    return ((CenterTable*)getParentBoard())->getGhostBoards().indexOf(this);
}

/*

  TILE BOARD CLASS


  */

TileBoard::TileBoard(GameTable * t, GameBoardOrganizer* b)
    :GameBoardOrganizer(t,b)
{
    int index = 0;
    for(int i=0; i<3; i++){
        for(int j=0; j<3; j++){
            VillageTile* singleVillage = new TeashopTile(this, i, j);
            villages << singleVillage;
            connect(singleVillage,SIGNAL(clicked(VillageTile*)),this,SIGNAL(clicked(VillageTile*)));
            indices[i][j] = index++;
        }
    }

}


// indices from top left (0,0) via centre (1,1) to bottom right (2,2)
VillageTile * TileBoard::getVillageAt( int x, int y )
{
    return villages.at( indices[x][y] );
}



/*

  PLAYER ICON ORGANIZER CLASS

*/

pIconOrganizer::pIconOrganizer(GameTable * t, GameBoardOrganizer * b)
    :GameBoardOrganizer(t,b)
{
    _pls = t->getPlayerList();
    _redPix = QPixmap(":/playerIcon/images/red.png");
    _yellowPix = QPixmap(":/playerIcon/images/yel_player.png");
    _greenPix = QPixmap(":/playerIcon/images/gre_player.png");
    _bluePix = QPixmap(":/playerIcon/images/blu_player.png");
    setIconsOnBoard();
}

void pIconOrganizer::setIconsOnBoard()
{
    PlayerIcon* redIcon;
    PlayerIcon* greenIcon;
    PlayerIcon* yellowIcon;
    PlayerIcon* blueIcon;

    yellowIcon = new PlayerIcon(this,_yellowPix,_pls.at(0));
    yellowIcon->moveBy(-_yellowPix.width()+EDGE_GAP,_yellowPix.height()-EDGE_GAP);
    _pls.at(0)->setPlayerIcon(yellowIcon);
    connect(_pls.at(0),SIGNAL(posChanged()),yellowIcon,SLOT(updateIconPos()));

    redIcon = new PlayerIcon(this,_redPix,_pls.at(1));
    redIcon->moveBy(-_redPix.width()+EDGE_GAP,-_redPix.height()+EDGE_GAP);
    _pls.at(1)->setPlayerIcon(redIcon);
    connect(_pls.at(1),SIGNAL(posChanged()),redIcon,SLOT(updateIconPos()));

    greenIcon = new PlayerIcon(this,_greenPix,_pls.at(2));
    greenIcon->moveBy(_greenPix.width()-EDGE_GAP,-_greenPix.height()+EDGE_GAP);
    _pls.at(2)->setPlayerIcon(greenIcon);
    connect(_pls.at(2),SIGNAL(posChanged()),greenIcon,SLOT(updateIconPos()));

    blueIcon = new PlayerIcon(this,_bluePix,_pls.at(3));
    blueIcon->moveBy(_bluePix.width()-EDGE_GAP,_bluePix.height()-EDGE_GAP);
    _pls.at(3)->setPlayerIcon(blueIcon);
    connect(_pls.at(3),SIGNAL(posChanged()),blueIcon,SLOT(updateIconPos()));

    iconItems << yellowIcon << redIcon << greenIcon << blueIcon;
    //connect to current player

}



/*

  CENTER TABLE CLASS

  */

CenterTable::CenterTable(GameTable* t)
    :GameBoardOrganizer(t)
{
    createBoards();
    //could do shuffle here
    setBoardPos();
    distributeBoardToPlayer();
    setBoardId();
    tileBoard = new TileBoard(getGameTable(), this);
    connect(tileBoard,SIGNAL(clicked(VillageTile*)),this,SIGNAL(clicked(VillageTile*)));
    playerIcons = new pIconOrganizer(this->getGameTable(),this);
}

QRectF CenterTable::boundingRect() const{
    return QRectF(-OUTWIDTH/2, -OUTHEIGHT/2, OUTWIDTH, OUTHEIGHT);
}


void CenterTable::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
    QPainterPath path;
    path.addRoundRect(boundingRect(), 5);
    painter->fillPath(path, Qt::white);
}

void CenterTable::createBoards(){
    GhostBoard* yel = new GhostBoard(getGameTable(), this, YELLOW);
    GhostBoard* red = new GhostBoard(getGameTable(), this, RED);
    GhostBoard* gre = new GhostBoard(getGameTable(), this, GREEN);
    GhostBoard* blu = new GhostBoard(getGameTable(), this, BLUE);
    board << yel << red << gre << blu;
    for(int i = 0; i<4; i++)
        connect(board[i], SIGNAL(clicked(GhostSlot*)), this, SIGNAL(clicked(GhostSlot*)));
}

void CenterTable::setBoardPos(){
    int tileWidth = VillageTile::WIDTH;
    //board1
    board[0]->moveBy(0, tileWidth*3/2+GhostSlot::HEIGHT/2);

    //board2
    board[1]->rotate(-90);
    board[1]->moveBy(tileWidth*3/2+GhostSlot::HEIGHT/2, 0);

    //board2
    board[2]->moveBy(0, -tileWidth*3/2-GhostSlot::HEIGHT/2);
    board[2]->rotate(-180);

    //board2
    board[3]->moveBy(-tileWidth*3/2-GhostSlot::HEIGHT/2, 0);
    board[3]->rotate(90);
}

void CenterTable::setBoardId(){
    for(int i = 0; i<4; i++)
        board[i]->setId(i);
}

void CenterTable::distributeBoardToPlayer(){
    QList<Player*> plist = getGameTable()->getPlayerList();
    for(int i = 0; i<4; i++){
        plist[i]->receiveBoard(board[i]);
    }
}





//**********************************LEFT TABLE********************************//
/*

  LEFT TABLE CLASS

  */

LeftTable::LeftTable(GameTable* t)
    :GameBoardOrganizer(t)
{
    _info_board = new InfoBoard( this->getGameTable(), this );
}

QRectF LeftTable::boundingRect() const{
    return QRectF(-OUTWIDTH/2, -OUTHEIGHT/2, OUTWIDTH, OUTHEIGHT);
}

void LeftTable::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){

    QPainterPath p;
    p.addRoundRect(boundingRect(), 10);
    painter->fillPath(p, QBrush(Qt::white));


}


//**********************************RIGHT TABLE********************************//
/*

  RIGHT TABLE CLASS

  */

RightTable::RightTable(GameTable* t)
    :GameBoardOrganizer(t)
{
    _deck_board = new DeckBoard( t, this );

    InfoBoard * info_board =
            ((GameTable*) this->parentObject())->getInfoBoard();
    if( info_board )
        _deck_board->link_to_info( info_board );
}

QRectF RightTable::boundingRect() const{
    return QRectF(-OUTWIDTH/2, -OUTHEIGHT/2, OUTWIDTH, OUTHEIGHT);
}

void RightTable::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){

    QPainterPath p;
    p.addRoundRect(boundingRect(), 10);
    painter->fillPath(p, QBrush(Qt::white));

}


//**********************************Bottom TABLE********************************//



/*

  bottom TABLE CLASS

  */

BottomTable::BottomTable(GameTable* t)
    :GameBoardOrganizer(t)
{
    setAcceptHoverEvents(true);
    _pl = this->getGameTable()->getCurrentPlayer();
    BasicField = new PlayerBasic(t,this,_pl);
    BasicField->moveBy(-WIDTH/2+PlayerBasic::BASIC_WIDTH-(PlayerBasic::BASIC_WIDTH-PlayerHead::WIDTH)/2,0);

    TaoField = new PlayerTaoField(t,this,_pl);
    TaoField->moveBy(-WIDTH/2+PlayerBasic::BASIC_WIDTH+10
                     +PlayerTaoField::FIELD_WIDTH/2,0);
    ActionField = new PlayerAction(t,this,_pl);
    ActionField->setPos(-WIDTH/2+PlayerBasic::BASIC_WIDTH+10
                        +PlayerTaoField::FIELD_WIDTH+PlayerAction::ACTION_WIDTH/2,0);
    moveBy(0, CenterTable::OUTHEIGHT/2+OUTHEIGHT/2+10);
}

QRectF BottomTable::boundingRect() const{
    return QRectF(-OUTWIDTH/2, -OUTHEIGHT/2, OUTWIDTH, OUTHEIGHT);
}



void BottomTable::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
    QPainterPath p;
    p.setFillRule(Qt::WindingFill);
    p.addRoundRect(QRectF(-OUTWIDTH/2, -OUTHEIGHT/2, OUTWIDTH, OUTHEIGHT), 15);
    //p.addRoundRect(-OUTWIDTH/2, -OUTHEIGHT/2-PlayerHead::HEIGHT+HEIGHT, 130, 130, 15);
    painter->fillPath(p, QBrush(Qt::white));
    painter->fillRect(QRectF(-WIDTH/2, -HEIGHT/2, WIDTH, HEIGHT), _pl->getGhostBoard()->getColor());
    //painter->fillRect(boundingRect(), Qt::white);

}


